package com.mlethe.library.fingerprint;

import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.fragment.app.FragmentActivity;

import com.mlethe.library.fingerprint.callback.FingerprintCallback;
import com.mlethe.library.fingerprint.callback.IFingerprint;
import com.mlethe.library.fingerprint.entity.VerificationDialogStyle;

/**
 * Android M == 6.0
 * Created by Mlethe on 2019/7/9.
 */
@RequiresApi(api = Build.VERSION_CODES.M)
class FingerprintImplForAndroidM implements IFingerprint {

    /**
     * 指纹验证框
     */
    private FingerprintDialog fingerprintDialog;

    /**
     * 指向调用者的指纹回调
     */
    private FingerprintCallback fingerprintCallback;

    /**
     * 指纹识别弹窗
     */
    private FingerprintImplForNoDialog fingerprintImplForNoDialog;

    /**
     * 弹窗样式
     */
    private VerificationDialogStyle verificationDialogStyle;

    /**
     * 指纹识别回调
     */
    private FingerprintCallback mFingerprintCallback = new FingerprintCallback() {
        @Override
        public void onHwUnavailable() {
            if (fingerprintCallback != null) {
                fingerprintCallback.onHwUnavailable();
            }
            dismissAllowingStateLoss();
            onDestroy();
        }

        @Override
        public void onNoneEnrolled() {
            if (fingerprintCallback != null) {
                fingerprintCallback.onNoneEnrolled();
            }
            dismissAllowingStateLoss();
            onDestroy();
        }

        @Override
        public void onSucceeded() {
            if (fingerprintCallback != null) {
                fingerprintCallback.onSucceeded();
            }
            dismissAllowingStateLoss();
            onDestroy();
        }

        @Override
        public void onChange() {
            if (fingerprintCallback != null) {
                fingerprintCallback.onChange();
            }
            dismissAllowingStateLoss();
            onDestroy();
        }

        @Override
        public void onFailed(String msg) {
            if (fingerprintDialog != null) {
                fingerprintDialog.showFail(msg, "#FF5555");
            }
            if (fingerprintCallback != null) {
                fingerprintCallback.onFailed(msg);
            }
        }

        @Override
        public void onError(String msg) {
            if (fingerprintDialog != null) {
                fingerprintDialog.showError(msg, "#FF5555", new Runnable() {
                    @Override
                    public void run() {
                        if (fingerprintCallback != null) {
                            fingerprintCallback.onError(msg);
                        }
                        onDestroy();
                    }
                });
            }
        }

        @Override
        public void onCancel() {
            if (fingerprintCallback != null) {
                fingerprintCallback.onCancel();
            }
            dismissAllowingStateLoss();
            onDestroy();
        }
    };

    private static final class Holder {
        private static final FingerprintImplForAndroidM INSTANCE = new FingerprintImplForAndroidM();
    }

    private FingerprintImplForAndroidM() {
    }

    public static FingerprintImplForAndroidM getInstance() {
        FingerprintImplForAndroidM instance = Holder.INSTANCE;
        instance.fingerprintImplForNoDialog = FingerprintImplForNoDialog.getInstance();
        return instance;
    }

    @Override
    public boolean createCryptoObject(boolean isSetting) {
        return fingerprintImplForNoDialog.createCryptoObject(isSetting);
    }

    /**
     * 调起指纹验证
     *
     * @param context
     */
    @Override
    public void authenticate(@NonNull Context context) {
        if (context instanceof FragmentActivity) {
            // 指纹验证框
            fingerprintDialog = new FingerprintDialog()
                    .setDialogStyle(verificationDialogStyle)
                    .setOnDismissListener(new DialogInterface.OnDismissListener() {
                        @Override
                        public void onDismiss(DialogInterface dialog) {
                            // 取消指纹验证
                            cancel();
                        }
                    });
            FragmentActivity activity = (FragmentActivity) context;
            fingerprintDialog.showAllowingStateLoss(activity.getSupportFragmentManager());
        } else {
            if (fingerprintCallback != null) {
                fingerprintCallback.onError("Context must is FragmentActivity");
            }
            onDestroy();
            return;
        }
        fingerprintImplForNoDialog.setFingerprintCallback(mFingerprintCallback);
        fingerprintImplForNoDialog.authenticate(context);
    }

    /**
     * 设置回调监听
     *
     * @param callback
     */
    @Override
    public void setFingerprintCallback(FingerprintCallback callback) {
        fingerprintCallback = callback;
    }

    /**
     * 设置弹窗样式
     *
     * @param verificationDialogStyle
     */
    @Override
    public void setVerificationDialogStyle(VerificationDialogStyle verificationDialogStyle) {
        this.verificationDialogStyle = verificationDialogStyle;
    }

    /**
     * 在 Android Q，Google 提供了 Api BiometricManager.canAuthenticate() 用来检测指纹识别硬件是否可用及是否添加指纹
     * 不过尚未开放，标记为"Stub"(存根)
     * 所以暂时还是需要使用 Andorid 6.0 的 Api 进行判断
     */
    @Override
    public boolean canAuthenticate(Context context) {
        return fingerprintImplForNoDialog.canAuthenticate(context);
    }

    @Override
    public void cancel() {
        if (fingerprintImplForNoDialog != null) {
            fingerprintImplForNoDialog.cancel();
        }
    }

    @Override
    public void onDestroy() {
        fingerprintDialog = null;
        fingerprintCallback = null;
    }

    /**
     * 关闭弹窗
     */
    private void dismissAllowingStateLoss() {
        if (fingerprintDialog != null && fingerprintDialog.isVisible()) {
            fingerprintDialog.dismissAllowingStateLoss();
        }
    }
}
